package com.stx.jeepay.payment.controller.qr;

import com.alipay.api.AlipayApiException;
import com.stx.jeepay.core.entity.PayOrderEntity;
import com.stx.jeepay.core.enums.CS;
import com.stx.jeepay.core.expection.BizException;
import com.stx.jeepay.core.model.ApiRes;
import com.stx.jeepay.core.service.PayOrderService;
import com.stx.jeepay.core.service.SysConfigService;
import com.stx.jeepay.core.utils.JeepayKit;
import com.stx.jeepay.core.utils.SpringBeansUtil;
import com.stx.jeepay.payment.channel.IChannelUserService;
import com.stx.jeepay.payment.controller.payorder.AbstractPayOrderController;
import com.stx.jeepay.payment.model.MchAppConfigContext;
import com.stx.jeepay.payment.rqrs.payorder.payway.AliJsapiOrderRQ;
import com.stx.jeepay.payment.rqrs.payorder.payway.WxJsapiOrderRQ;
import com.stx.jeepay.payment.service.ConfigContextQueryService;
import com.stx.jeepay.payment.service.PayMchNotifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 聚合码支付二维码收银台controller
 */
@RestController
@RequestMapping("/api/cashier")
public class QrCashierController extends AbstractPayOrderController {

    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private ConfigContextQueryService configContextQueryService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private PayMchNotifyService payMchNotifyService;

    /**
     * 返回 oauth2【获取uerId跳转地址】
     **/
    @PostMapping("/redirectUrl")
    public ApiRes redirectUrl() {
        //查询订单
        PayOrderEntity payOrder = getPayOrder();

        //回调地址
        String redirectUrlEncode =
                sysConfigService.getDBApplicationConfig().genOauth2RedirectUrlEncode(payOrder.getPayOrderId());

        //获取商户配置信息
        MchAppConfigContext mchAppConfigContext =
                configContextQueryService.queryMchInfoAndAppInfo(payOrder.getMchNo(), payOrder.getAppId());

        //获取接口并返回数据
        IChannelUserService channelUserService = getServiceByWayCode(getWayCode(), "ChannelUserService", IChannelUserService.class);
        return ApiRes.ok(channelUserService.buildUserRedirectUrl(redirectUrlEncode, mchAppConfigContext));
    }

    /**
     * 获取userId
     **/
    @PostMapping("/channelUserId")
    public ApiRes channelUserId() throws Exception {
        // 查询订单
        PayOrderEntity payOrder = getPayOrder();
        String wayCode = getWayCode();

        //获取商户配置信息
        MchAppConfigContext mchAppConfigContext = configContextQueryService.queryMchInfoAndAppInfo(payOrder.getMchNo(), payOrder.getAppId());
        IChannelUserService channelUserService = getServiceByWayCode(wayCode, "ChannelUserService", IChannelUserService.class);
        return ApiRes.ok(channelUserService.getChannelUserId(getReqParamJSON(), mchAppConfigContext));
    }

    /**
     * 获取订单支付信息
     **/
    @PostMapping("/payOrderInfo")
    public ApiRes payOrderInfo() throws Exception {
        //查询订单
        PayOrderEntity payOrder = getPayOrder();

        PayOrderEntity resOrder = new PayOrderEntity();
        resOrder.setPayOrderId(payOrder.getPayOrderId());
        resOrder.setMchOrderNo(payOrder.getMchOrderNo());
        resOrder.setMchName(payOrder.getMchName());
        resOrder.setAmount(payOrder.getAmount());
        resOrder.setReturnUrl(payMchNotifyService.createReturnUrl(payOrder, configContextQueryService.queryMchInfoAndAppInfo(payOrder.getMchNo(), payOrder.getAppId()).getMchApp().getAppSecret()));
        return ApiRes.ok(resOrder);
    }

    /**
     * 调起下单接口, 返回支付数据包
     **/
    @PostMapping("/pay")
    public ApiRes pay() throws Exception {
        PayOrderEntity payOrder = getPayOrder();

        String wayCode = getWayCode();

        ApiRes apiRes = null;

        if (wayCode.equals(CS.PAY_WAY_CODE.ALI_JSAPI)) {
            apiRes = packageAlipayPayPackage(payOrder);
        } else if (wayCode.equals(CS.PAY_WAY_CODE.WX_JSAPI)) {
            apiRes = packageWxpayPayPackage(payOrder);
        }

        return ApiRes.ok(apiRes);
    }

    /**
     * 获取支付宝的 支付参数
     **/
    private ApiRes packageAlipayPayPackage(PayOrderEntity payOrder) throws AlipayApiException {
        String channelUserId = getValStringRequired("channelUserId");
        AliJsapiOrderRQ rq = new AliJsapiOrderRQ();
        rq.setBuyerUserId(channelUserId);
        return this.unifiedOrder(getWayCode(), rq, payOrder);
    }

    /**
     * 获取微信的 支付参数
     **/
    private ApiRes packageWxpayPayPackage(PayOrderEntity payOrder) throws AlipayApiException {

        String openId = getValStringRequired("channelUserId");
        WxJsapiOrderRQ rq = new WxJsapiOrderRQ();
        rq.setOpenid(openId);
        return this.unifiedOrder(getWayCode(), rq, payOrder);
    }

    private PayOrderEntity getPayOrder() {
        String payOrderId = JeepayKit.aesDecode(getToken()); //解析token
        PayOrderEntity payOrder = payOrderService.getById(payOrderId);
        if (payOrder == null || payOrder.getState() != PayOrderEntity.STATE_INIT) {
            throw new BizException("订单不存在或订单状态不正确");
        }

        return payOrder;
    }

    private String getToken() {
        return getValStringRequired("token");
    }

    private <T> T getServiceByWayCode(String wayCode, String serviceSuffix, Class<T> cls) {

        if (CS.PAY_WAY_CODE.ALI_JSAPI.equals(wayCode)) {
            return SpringBeansUtil.getBean(CS.IF_CODE.ALIPAY + serviceSuffix, cls);
        } else if (CS.PAY_WAY_CODE.WX_JSAPI.equals(wayCode)) {
            return SpringBeansUtil.getBean(CS.IF_CODE.WXPAY + serviceSuffix, cls);
        }

        return null;
    }

    private String getWayCode() {
        return getValStringRequired("wayCode");
    }
}
